package com.mine.modules.vm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mine.common.config.exception.MineBootException;
import com.mine.common.domain.dto.LoginModel;
import com.mine.common.domain.vo.Result;
import com.mine.common.utils.ToTreeUtil;
import com.mine.common.utils.oConvertUtils;
import com.mine.modules.sys.domain.dto.RoleDto;
import com.mine.modules.sys.service.ISysUserRoleService;
import com.mine.modules.vm.domain.dto.VmPermissionDto;
import com.mine.modules.vm.entity.VmPermission;
import com.mine.modules.vm.entity.VmRolePermission;
import com.mine.modules.vm.mapper.VmPermissionMapper;
import com.mine.modules.vm.service.IVmPermissionService;
import com.mine.modules.vm.service.IVmRolePermissionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 场景菜单表 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-10-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class VmPermissionServiceImpl extends ServiceImpl<VmPermissionMapper, VmPermission> implements IVmPermissionService {

    private final IVmRolePermissionService vmRolePermissionService;

    private final ISysUserRoleService userRoleService;

    @Override
    public Result<?> listAll(String keywords, HttpServletRequest req) {
        long start = System.currentTimeMillis();
        try {
            //直接获取当前用户不适用前端token
            LoginModel loginUser = (LoginModel) SecurityUtils.getSubject().getPrincipal();
            if (oConvertUtils.isEmpty(loginUser)) {
                return Result.error("请登录系统！");
            }
            LambdaQueryWrapper<VmPermission> queryWrapper = new LambdaQueryWrapper<>();
            //权限过滤
            queryWrapper.and(StringUtils.isNotBlank(keywords), e -> e
                    .like(VmPermission::getName, keywords)
                    .or()
                    .like(VmPermission::getPath, keywords)
                    .or()
                    .like(VmPermission::getComponent, keywords)
                    .or()
                    .like(VmPermission::getComponentName, keywords)
            );
            queryWrapper.orderByAsc(VmPermission::getSortNo);
            List<VmPermission> list =list(queryWrapper);
            List<VmPermission> treeList = new ArrayList<>();
            //如果有菜单名查询条件，则平铺数据 不做上下级
            if (StringUtils.isNotEmpty(keywords)) {
                if (list != null && list.size() > 0) {
                    treeList = list;
                }
            } else {
                ToTreeUtil.getTreeList(treeList, list, null);
            }
            log.info("======获取全部场景菜单数据=====耗时:{}毫秒", System.currentTimeMillis() - start);
            return Result.OK("查询成功！", treeList);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error(e.getMessage());
        }
    }

    @Override
    public Result<?> addOrEdit(VmPermissionDto permissionDto) {
        if (permissionDto == null) {
            return Result.error("参数必填！");
        }
        if (StringUtils.isEmpty(permissionDto.getId())) {
            //新增
            VmPermission vmPermission = BeanUtil.toBean(permissionDto, VmPermission.class);
            if (this.save(vmPermission)) {
                return Result.OK("添加成功！");
            } else {
                return Result.error("添加失败！");
            }
        } else {
            VmPermission vmPermission = this.getById(permissionDto.getId());
            if (vmPermission == null) {
                return Result.error("数据不存在，请刷新重试！");
            }
            vmPermission = BeanUtil.toBean(permissionDto, VmPermission.class);
            if (this.updateById(vmPermission)) {
                return Result.OK("修改成功！");
            } else {
                return Result.error("修改失败！");
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> delete(String id) {
        try {
            this.deletePermission(id);
            return Result.OK("删除成功!");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error(e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> deleteBatch(String ids) {
        try {
            String[] arr = ids.split(",");
            for (String id : arr) {
                if (oConvertUtils.isNotEmpty(id)) {
                    try {
                        this.deletePermission(id);
                    } catch (MineBootException e) {
                        if (e.getMessage() != null && e.getMessage().contains("未找到菜单信息")) {
                            log.warn(e.getMessage());
                        } else {
                            throw e;
                        }
                    }
                }
            }
            return Result.OK("删除成功!");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("删除失败!");
        }
    }

    @Override
    public Result<List<String>> queryRolePermission(String roleId) {
        Result<List<String>> result = new Result<>();
        try {
            List<VmRolePermission> list = vmRolePermissionService.list(new QueryWrapper<VmRolePermission>().lambda().eq(VmRolePermission::getRoleId, roleId));
            result.setResult(list.stream().map(vmRolePermission -> String.valueOf(vmRolePermission.getPermissionId())).collect(Collectors.toList()));
            result.success("查询成功！");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return result;
    }

    @Override
    public Result<?> saveRolePermission(RoleDto roleDto) {
        long start = System.currentTimeMillis();
        Result<String> result = new Result<>();
        try {
            String roleId = roleDto.getRoleId();
            String permissionIds = roleDto.getPermissionIds();
            String lastPermissionIds = roleDto.getLastpermissionIds();
            this.vmRolePermissionService.saveRolePermission(roleId, permissionIds, lastPermissionIds);
            LoginModel loginUser = (LoginModel) SecurityUtils.getSubject().getPrincipal();
            result.success("操作成功！");
            log.info("======角色授权成功=====耗时:{}毫秒", System.currentTimeMillis() - start);
        } catch (Exception e) {
            result.error500("授权失败！");
            log.error(e.getMessage(), e);
        }
        return result;
    }

    @Override
    public Result<?> getUserPermissionByToken() {
        try {
            //直接获取当前用户不适用前端token
            LoginModel loginUser = (LoginModel) SecurityUtils.getSubject().getPrincipal();
            if (oConvertUtils.isEmpty(loginUser)) {
                return Result.error("请登录系统！");
            }
            LambdaQueryWrapper<VmPermission> queryWrapper = new LambdaQueryWrapper<>();
            //权限过滤
            List<String> permissionIds = null;
            if (!StringUtils.equals("admin", loginUser.getUsername())) {
                permissionIds = vmRolePermissionService.getPermissionIdsByRoleIds(
                        userRoleService.getRoleIdsByUerId(loginUser.getId())
                );
                if (permissionIds == null || permissionIds.isEmpty()) {
                    return Result.error("该用户未授权菜单！！");
                }
                queryWrapper.in(VmPermission::getId, permissionIds);
            }
            queryWrapper.orderByAsc(VmPermission::getSortNo);
            List<VmPermission> list =list(queryWrapper);
            List<VmPermission> treeList = new ArrayList<>();
            ToTreeUtil.getTreeList(treeList, list, null);
            return Result.OK("查询成功！", treeList);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error(e.getMessage());
        }
    }

    private void deletePermission(String id) {
        VmPermission vmPermission = this.getById(id);
        if (vmPermission == null) {
            throw new MineBootException("未找到菜单信息");
        }
        this.removeById(id);
        // 该节点可能是子节点但也可能是其它节点的父节点,所以需要级联删除
        this.removeChildrenBy(id);
    }

    /**
     * 根据父id删除其关联的子节点数据
     */
    public void removeChildrenBy(String parentId) {
        LambdaQueryWrapper<VmPermission> query = new LambdaQueryWrapper<>();
        // 封装查询条件parentId为主键,
        query.eq(VmPermission::getParentId, parentId);
        // 查出该主键下的所有子级
        List<VmPermission> permissionList = this.list(query);
        if (permissionList != null && !permissionList.isEmpty()) {
            String id = "";
            // 查出的子级数量
            long num = 0;
            // 如果查出的集合不为空, 则先删除所有
            this.remove(query);
            // 再遍历刚才查出的集合, 根据每个对象,查找其是否仍有子级
            for (VmPermission vmPermission : permissionList) {
                id = vmPermission.getId();
                //删除角色授权表
                vmRolePermissionService.remove(new LambdaQueryWrapper<VmRolePermission>().eq(VmRolePermission::getPermissionId, id));
                num = this.count(new LambdaQueryWrapper<VmPermission>().eq(VmPermission::getParentId, id));
                if (num > 0) {
                    this.removeChildrenBy(id);
                }
            }
        }
    }

}
